var CRC = {};


CRC.CRC16 = function (buffer) {
    return CRC.crc16_ccitt_xmodem( buffer, 0, buffer.length)    
};

 CRC.crc16_ccitt_xmodem = function( bytes, offset, count) {
    var crc = 0x7319; // initial value
    var polynomial = 0x1021; // poly value
    for (var index = offset; index < count; index++) {
          var b = bytes[index];
          for (var i = 0; i < 8; i++) {
          var bit = ((b >> (7 - i) & 1) == 1);
          var c15 = ((crc >> 15 & 1) == 1);
          crc <<= 1;
          if (c15 ^ bit)
          crc ^= polynomial;
      }
    }
    crc &= 0xffff;
    let code = crc.toString(16).toUpperCase();
    return CRC.pad(code,4);
};

//补齐数据
CRC.pad = function(num, n) {
    var len = num.toString().length;
    while (len < n) {
       num = '0' + num;
       len++;
    }
    return num;
};


CRC.isArray = function (arr) {
    return Object.prototype.toString.call(arr) === '[object Array]';
};

CRC.ToCRC16 = function (str) {
    return CRC.CRC16(CRC.isArray(str) ? str : CRC.strToByte(str));
};

CRC.ToModbusCRC16 = function (str) {
    return CRC.CRC16(CRC.isArray(str) ? str : CRC.strToHex(str));
};

CRC.strToByte = function (str) {
    var tmp = str.split(''), arr = [];
    for (var i = 0, c = tmp.length; i < c; i++) {
        var j = encodeURI(tmp[i]);
        if (j.length == 1) {
            arr.push(j.charCodeAt());
        } else {
            var b = j.split('%');
            for (var m = 1; m < b.length; m++) {
                arr.push(parseInt('0x' + b[m]));
            }
        }
    }
    return arr;
};

CRC.convertChinese = function (str) {
    var tmp = str.split(''), arr = [];
    for (var i = 0, c = tmp.length; i < c; i++) {
        var s = tmp[i].charCodeAt();
        if (s <= 0 || s >= 127) {
            arr.push(s.toString(16));
        }
        else {
            arr.push(tmp[i]);
        }
    }
    return arr;
};

CRC.filterChinese = function (str) {
    var tmp = str.split(''), arr = [];
    for (var i = 0, c = tmp.length; i < c; i++) {
        var s = tmp[i].charCodeAt();
        if (s > 0 && s < 127) {
            arr.push(tmp[i]);
        }
    }
    return arr;
};

CRC.strToHex = function (hex, isFilterChinese) {
    hex = isFilterChinese ? CRC.filterChinese(hex).join('') : CRC.convertChinese(hex).join('');

    //清除所有空格
    hex = hex.replace(/\s/g, "");
    //若字符个数为奇数，补一个空格
    hex += hex.length % 2 != 0 ? " " : "";

    var c = hex.length / 2, arr = [];
    for (var i = 0; i < c; i++) {
        arr.push(parseInt(hex.substr(i * 2, 2), 16));
    }
    return arr;
};

// CRC.padLeft = function (s, w, pc) {
//     if (pc == undefined) {
//         pc = '0';
//     }
//     for (var i = 0, c = w - s.length; i < c; i++) {
//         s = pc + s;
//     }
//     return s;
// };


module.exports = CRC;